<template>
	<u-popup class="select-popup" v-model="visible" mode="bottom" border-radius="0" :before-close="beforeClose">
		<view class="select-popup-wrap">
			<view class="select-popup-head">
				<text @click="onCancel">取消</text>
				<view v-if="filterable" class="select-popup-head_search">
					<text class="iconfont icon-search"></text>
					<input v-model="otherVal" type="text" placeholder="输入关键词进行搜索">
				</view>
				<text v-else>{{ title }}</text>
				<text class="select-popup-head_btn-submit" @click="onSubmit">确定</text>
			</view>
			<scroll-view class="scroll-view" scroll-y="true">
				<view class="select-popup-list">
					<view v-if="allowCreate && !isValueInList && otherVal" class="select-popup-item"
						:class="selectSearchClasses" @click="selectItemSearch">
						{{ otherVal }}</view>
					<view class="select-popup-item" :class="selectItemClasses(item)" v-for="item in searchFilterList"
						:key="item[valueText]" @click="selectItem(item)">
						<text class="text">{{ item[labelText] }}</text>
						<text>{{ descKey(item) }}</text>
					</view>
				</view>
				<view v-if="!searchFilterList.length && !otherVal" style="height: 100%;">
					<u-empty text="暂无数据" mode="list" icon-size="300" font-size="60"></u-empty>
				</view>
			</scroll-view>
		</view>
	</u-popup>
</template>

<script>
import { getNestedValue } from '@/utils/index.js'
export default {
	name: 'SelectList',
	model: {
		prop: 'value',
		event: 'input'
	},
	props: {
		value: {
			type: [String, Number],
			default: ''
		},
		list: {
			type: Array,
			default: () => ([])
		},
		visible: {
			type: Boolean,
			default: false
		},
		title: String,
		labelText: {
			type: String,
			default: 'label'
		},
		valueText: {
			type: String,
			default: 'value'
		},
		descText: {
			type: String,
			default: 'desc'
		},
		multiple: {
			type: Boolean,
			default: false
		},
		filterable: {
			type: Boolean,
			default: false
		},
		allowCreate: {
			type: Boolean,
			default: false
		},
	},
	data() {
		return {
			selectIndex: null,
			otherVal: '',
			searchList: [],
		}
	},
	computed: {
		listVal() {
			return {
				list: this.list,
				value: this.value.toString()
			}
		},
		descKey() {
			return (item) => {
				return getNestedValue(item, this.descText)
			}
		},
		selectItemClasses() {
			return (item) => {
				if (!this.selectIndex) return ''
				const selectIndex = this.selectIndex
				const isSelected = this.multiple ? selectIndex.some(id => id == item[this.valueText]) : selectIndex[0] == item[this.valueText];
				return { 'selected': isSelected };
			}
		},
		selectSearchClasses() {
			const searchVal = this.otherVal
			const isSelected = this.searchList.some(item => item[this.labelText] == searchVal)
			return { 'selected': isSelected };
		},
		searchFilterList() {
			const searchVal = this.otherVal
			const list = this.list.filter(item => item[this.labelText].includes(searchVal))
			return list
		},
		// 用于判断是否隐藏 根据 输入产生的搜索项
		isValueInList() {
			const val = this.otherVal
			const hasValInList = this.list.some(item => item[this.labelText] == val)
			return hasValInList
		}
	},
	watch: {
		visible: {
			handler(val) {
				if (val) {
					this.selectIndex = this.value.split(',').filter(Boolean) || []
				}
			}
		},
		listVal: {
			handler(n) {
				this.change(n.value)
			},
			immediate: true
		},
	},
	methods: {
		change(value) {
			if (!value) return
			const list = this.list
			const vals = this.selectIndex = value.split(',').filter(Boolean) || []
			let arr = [];
			for (let i = 0; i < list.length; i++) {
				let ele = list[i];
				let valKey = getNestedValue(ele, this.valueText)
				let flag = vals.some(id => id == valKey)
				if (flag) {
					arr.push(ele);
				}
			}
			const params = Object.assign({}, { list: list, item: arr, value: value })

			this.$emit('change', params)
		},
		selectItem(item) {
			const value = item[this.valueText]
			// 如果是空 则直接赋值
			if (!this.selectIndex && !this.selectIndex?.length) return this.selectIndex = [value]

			const selectIndex = this.selectIndex

			// 检测 当前选中的是否有被点击的项
			const flag = selectIndex.some(id => id == value)
			if (flag) {
				if (!this.multiple) {
					this.selectIndex = []
				} else {

					let index = selectIndex.findIndex(id => id == value);
					if (index !== -1) {
						selectIndex.splice(index, 1)
						this.selectIndex = selectIndex
					}
				}
				return
			}

			if (!this.multiple) {
				this.selectIndex = [value]
			} else {
				selectIndex.push(value)
				this.selectIndex = selectIndex
			}
		},
		selectItemSearch() {
			const searchVal = this.otherVal
			const selectIndex = this.selectIndex

			// 检测 当前选中的是否有被点击的项
			if (selectIndex.includes(searchVal)) {
				if (!this.multiple) {
					this.selectIndex = []
					this.searchList = []
				} else {
					const index = selectIndex.findIndex(id => id == searchVal);
					const searchIndex = this.searchList.findIndex(id => id == searchVal);
					if (index !== -1) {
						selectIndex.splice(index, 1)
						this.searchList.splice(searchIndex, 1)
						this.selectIndex = selectIndex
					}
				}
				return
			}
			this.otherVal = ''
			if (!this.selectIndex && !this.selectIndex.length) {
				this.searchList.push({ [this.labelText]: searchVal, [this.valueText]: searchVal });
				return this.selectIndex = [searchVal];
			}

			if (!this.multiple) {
				this.selectIndex = [searchVal]
			} else {
				selectIndex.push(searchVal)
				this.selectIndex = selectIndex
			}

			this.searchList.push({ [this.labelText]: searchVal, [this.valueText]: searchVal })
		},
		beforeClose(done) {
			this.$emit('update:visible', false)
			this.selectIndex = null
			this.otherVal = ''
			done()
		},
		onCancel() {
			this.$emit('update:visible', false)
			this.selectIndex = null
			this.otherVal = ''
		},
		onSubmit() {
			const val = this.selectIndex.join(',')
			this.$emit('update:visible', false)
			this.$emit('input', val)
			this.selectIndex = null
			this.otherVal = ''
		}
	}
}
</script>
<style scoped lang="scss">
.select-popup {

	&-head {
		display: flex;
		align-items: center;
		justify-content: space-between;
		width: 100%;
		height: 90rpx;
		font-size: 30rpx;
		padding: 0 40rpx;
		position: relative;

		&>text {
			cursor: pointer;
		}

		&::after {
			content: '';
			border-bottom: 1px solid #eaeef1;
			position: absolute;
			transform: scaleY(0.5);
			bottom: 0;
			right: 0;
			left: 0;
		}

		&-btn_submit {
			color: $u-type-primary;
		}

		&_search {
			width: 50%;
			height: 70%;
			margin: auto;
			display: flex;
			align-items: center;
			background: #f1f1f1;
			border-radius: 20rpx;
			padding: 0 30rpx;

			.icon-search {
				margin-right: 10rpx;
			}

			input {
				flex: 1;
			}
		}
	}

	.scroll-view {
		height: calc(60vh - 90rpx);
	}

	&-item {
		height: 60rpx;
		line-height: 60rpx;
		padding: 0 40rpx;
		display: flex;
		justify-content: space-between;
		cursor: pointer;

		.text {
			flex: 1;
		}

		&::after {
			margin-left: 6rpx;
			min-width: 32rpx;
			content: '';
		}

		&.selected {
			color: $u-type-primary;
			background-color: #fff;

			&::after {
				font-family: "iconfont" !important;
				font-size: 16px;
				font-style: normal;
				-webkit-font-smoothing: antialiased;
				-moz-osx-font-smoothing: grayscale;
				content: '\e63c';
			}
		}
	}
}
</style>